package com.jy.modules.cims.deal.service;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.jy.modules.cims.common.CimsConstant;
import com.jy.modules.cims.common.JResult;
import com.jy.modules.cims.component.common.service.TCMmCooperorgDealService;
import com.jy.modules.cims.component.common.service.TCMmCreditDealDetailService;
import com.jy.modules.cims.component.common.service.TCMmCreditDetailService;
import com.jy.modules.cims.component.common.service.TCMmCreditPackageService;
import com.jy.modules.cims.component.deal.ICDeal;
import com.jy.modules.cims.creditright.service.CreditRightService;
import com.jy.modules.cims.data.common.dao.TCMmCreditDealDetailDao;
import com.jy.modules.cims.data.common.dao.TCMmCreditDetailDao;
import com.jy.modules.cims.data.common.dao.TCMmCreditTimeoutDao;
import com.jy.modules.cims.data.common.dto.TCMmCooperorgDealDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditDealDetailDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditDetailDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditPackageDTO;
import com.jy.modules.cims.data.common.dto.TCMmCreditTimeoutDTO;
import com.jy.modules.cims.data.dao.DealDao;
import com.jy.modules.cims.data.dto.CreditDetailDto;
import com.jy.modules.cims.data.dto.DealDto;
import com.jy.platform.core.message.DataMsg;
import com.jy.platform.core.message.PageParameter;
import com.jy.platform.core.message.PageUtil;
import com.jy.platform.core.message.QueryReqBean;

@Service("com.jy.modules.cims.deal.service.TimeoutService")
public class TimeoutService implements Serializable {
	private static final long serialVersionUID = 1L;

	private static final Logger logger = LoggerFactory.getLogger(TimeoutService.class);
	
	@Autowired
	private TCMmCreditTimeoutDao timeoutDao;
	
	@Autowired
	public TCMmCreditDealDetailDao creditDealDetailDao;
	
	@Autowired
	private DealDao dealDao;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCooperorgDealService")
	private TCMmCooperorgDealService cooperorgDealService;
	
	@Autowired
	private TCMmCreditDetailDao creditDetailDao;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.creditright.service.CreditRightService")
	private CreditRightService creditRightService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditPackageService")
	private TCMmCreditPackageService creditPackageService;
	
	@Autowired
    @Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditDealDetailService")
    private TCMmCreditDealDetailService tCMmCreditDealDetailService;
	
	@Autowired
    @Qualifier("com.jy.modules.cims.component.common.service.TCMmCreditDetailService")
    private TCMmCreditDetailService tCMmCreditDetailService;
	
	@Autowired
	@Qualifier("com.jy.modules.cims.component.deal.CDealImpl")
	private ICDeal iCDeal;
	
	
	
	/**
	 * 更新操作
	 * @param creditDetailList
	 * @param batchId
	 * @param creditAffiliation
	 * @param cooperorgCode
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void updateInfo(List<CreditDetailDto> creditDetailList, String batchId, 
			String creditAffiliation, String cooperorgCode, String frontTransNo) throws Exception {
		if (CollectionUtils.isNotEmpty(creditDetailList)) {
			//更新债权明细(三费、交互状态、交割日、转让价值、计划赎回日期)
			updateDetails(creditDetailList);
			//更新关系表（三费、交互状态、结算标识、月还归属）
			updateRef(creditDetailList,batchId, creditAffiliation);
			//更新老批次表状态（总笔数、转让总价值、三费之和、总体状态）
			updateBatch(batchId);
			//删除超时表记录
			int cnt = timeoutDao.queryTimeoutCountByFrontNo(frontTransNo);
			if (cnt > 0) {
				timeoutDao.deleteTCMmCreditTimeoutByFrontNo(frontTransNo);
			}
		}
	}
	
	
	/**
	 * 更新明细
	 * 
	 * @param dealCode
	 * @return
	 */
	private void updateDetails(List<CreditDetailDto> creditDealList) throws Exception {
		for (CreditDetailDto creditDetailDto : creditDealList) {
			Map<String, Object> searchParams = new HashMap<String, Object>();
			TCMmCreditDetailDTO creditDetailDTO = new TCMmCreditDetailDTO();
			creditDetailDTO.setTransferId(creditDetailDto.getTransferId());
			searchParams.put("dto", creditDetailDTO);
			//查询明细表
			List<TCMmCreditDetailDTO> detailList = creditDetailDao.searchTCMmCreditDetail(searchParams);
			if (CollectionUtils.isEmpty(detailList)) {
				throw new RuntimeException("债权明细表找不到记录，转让编号=" + creditDetailDto.getTransferId());
			}
			creditDetailDTO = detailList.get(0);
			creditDetailDTO.setCreditorStatus(creditDetailDto.getDealCreditorStatus());// 交互状态
			creditDetailDTO.setMakeCreditorValue(creditDetailDto.getMakeCreditorValue());// 转让价值
			creditDetailDTO.setDeliverDate(creditDetailDto.getDeliverDate());// 交割日期
			//creditDetailDTO.setPlanRedeemDate(creditDetailDto.getPlanRedeemDate());//计划赎回日期
			creditDetailDTO.setServiceCharge(creditDetailDto.getServiceCharge());//服务费
			creditDetailDTO.setGuaranteeFee(creditDetailDto.getGuaranteeFee());//担保费
			creditDetailDTO.setCautionMoney(creditDetailDto.getCautionMoney());//保证金
			creditDetailDTO.setThisMakeCreditorValue(creditDetailDto.getThisMakeCreditorValue());//本次转让价值
			// 更新明细表
			searchParams.clear();
			searchParams.put("dto", creditDetailDTO);
			creditDetailDao.updateDetail(searchParams);

		}
	}

	
	
	/**
	 * 更新结算状态
	 * @param excelList
	 * @param batchId
	 */
	public void updateSettleInfo(List<CreditDetailDto> excelList, String batchId) {
		if (CollectionUtils.isNotEmpty(excelList)) {
			for (CreditDetailDto creditDetailDto : excelList) {
				String settleStatus = creditDetailDto.getCostState();//结算标识
				if (StringUtils.isNotBlank(settleStatus)) {
					//查询关系表
	    	        TCMmCreditDealDetailDTO creditDealDetaildto = new TCMmCreditDealDetailDTO();
					creditDealDetaildto.setTransferId(creditDetailDto.getTransferId());
//					creditDealDetaildto.setDealStreamCode(batchId);
					Map<String, Object> searchParamsdeal = new HashMap<String, Object>();
					searchParamsdeal.put("dto", creditDealDetaildto);
					List<TCMmCreditDealDetailDTO>  refList = creditDealDetailDao.searchTCMmCreditDealDetail(searchParamsdeal);
					if (CollectionUtils.isEmpty(refList)) {
						logger.warn("债权关系表找不到记录，转让编号=" + creditDetailDto.getTransferId());//excel可能存在任意脏数据
						continue;
					}
					creditDealDetaildto = refList.get(0);
					//如果结算状态不是【结算申请、已结算】，则更新结算状态
					String oldSettleStatus = creditDealDetaildto.getCostState();
					if (!CimsConstant.COST_STATUS_SQ.equals(oldSettleStatus) //结算申请
							&& !CimsConstant.COST_STATUS_YJ.equals(oldSettleStatus)) {//已结算
						//-----------------更新关系表的三费、结算状态
						creditDealDetaildto.setCostState(settleStatus);
						creditDealDetaildto.setServiceCharge(creditDetailDto.getServiceCharge());//服务费
						creditDealDetaildto.setGuaranteeFee(creditDetailDto.getGuaranteeFee());//担保费
						creditDealDetaildto.setCautionMoney(creditDetailDto.getCautionMoney());//保证金
						Map<String, Object> paramMap = new HashMap<String, Object>();
		    	        paramMap.put("dto", creditDealDetaildto);
		    	        creditDealDetailDao.updateDealDetailFee(paramMap);
						//-----------------更新明细表的三费
		    	    	//查询明细表
		    	        Map<String, Object> searchParams = new HashMap<String, Object>();
		    			TCMmCreditDetailDTO creditDetailDTO = new TCMmCreditDetailDTO();
		    			creditDetailDTO.setTransferId(creditDetailDto.getTransferId());
		    			searchParams.put("dto", creditDetailDTO);
		    			List<TCMmCreditDetailDTO> detailList = creditDetailDao.searchTCMmCreditDetail(searchParams);
		    			if (CollectionUtils.isEmpty(detailList)) {
		    				logger.warn("债权明细表找不到记录，转让编号=" + creditDetailDto.getTransferId());//excel可能存在任意脏数据
							continue;
		    			}
		    			creditDetailDTO = detailList.get(0);
		    			creditDetailDTO.setServiceCharge(creditDetailDto.getServiceCharge());//服务费
		    			creditDetailDTO.setGuaranteeFee(creditDetailDto.getGuaranteeFee());//担保费
		    			creditDetailDTO.setCautionMoney(creditDetailDto.getCautionMoney());//保证金
		    			// 更新明细表
		    			searchParams.clear();
		    			searchParams.put("dto", creditDetailDTO);
		    			creditDetailDao.updateDetailFee(searchParams);
					}
				}
			}
		} 
	}
	
	
	/**
	 * 保存超时记录
	 * @param detail
	 * @param frontTransNo
	 * @param interfaceNo
	 * @param batchId
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void saveTimeoutRecord(CreditDetailDto detail, String frontTransNo, 
			String interfaceNo, String batchId, String userId) {
		
		//超时表如果有记录则跳过
		String transferId = detail.getTransferId();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("frontTransNo", frontTransNo);
		paramMap.put("transferId", transferId);
		int count = timeoutDao.queryTimeoutCountByFrontNoAndTransId(paramMap);
		if (count > 0) {
			return;
		}
		
		TCMmCreditTimeoutDTO timeoutDto = new TCMmCreditTimeoutDTO();
		timeoutDto.setFrontTransNo(frontTransNo);//前端流水号
		timeoutDto.setRetCode("TIMEOUT");//核心返回码
		timeoutDto.setInterfaceNo(interfaceNo);//接口编码
		timeoutDto.setOperStatus(detail.getDealCreditorStatus());//交互状态
		timeoutDto.setDealCode(batchId);//批次号
		timeoutDto.setTransferId(detail.getTransferId());//转让编号
		timeoutDto.setCreditCode(detail.getCreditCode());//债权编号
		timeoutDto.setCorpCode(detail.getCooperorgCode());//合作机构编码
		timeoutDto.setIdNum(detail.getBorrowerIdNumber());//借款人身份证号
		timeoutDto.setBorrowerName(detail.getBorrowerName());//借款人姓名
		timeoutDto.setContractAmt(detail.getContractSum());//合同金额
		timeoutDto.setPackageNum(detail.getPackageNum());//所属包编号
		timeoutDto.setCooperorgPackageName(detail.getCooperorgPackageName());//机构理财包
		timeoutDto.setMakeCreditorValue(detail.getMakeCreditorValue());//转让价值
		timeoutDto.setThisMakeCreditorValue(detail.getThisMakeCreditorValue());//本次转让价值
		timeoutDto.setDeliverDate(detail.getDeliverDate());//交割日期
		timeoutDto.setRepayAmt(detail.getThisRepaySum());//本期月还
		timeoutDto.setServiceCharge(detail.getServiceCharge());//服务费
		timeoutDto.setGuaranteeFee(detail.getGuaranteeFee());//担保费
		timeoutDto.setCautionMoney(detail.getCautionMoney());//保证金
		//timeoutDto.setPlanRedeemDate(detail.getPlanRedeemDate());//计划赎回日期
		timeoutDto.setSettleStatus(detail.getCostState());//结算标识
		timeoutDto.setCreateBy(userId);
		timeoutDto.setModifyBy(userId);
		Map<String, Object> timeoutParamMap = new HashMap<String, Object>();
		timeoutParamMap.put("dto", timeoutDto);
		timeoutDao.insertTCMmCreditTimeout(timeoutParamMap);
	}
	
	
	
	/**
	 * 更新关系表
	 * 
	 */
	private void updateRef(List<CreditDetailDto> creditDetailList,String batchId,String creditAffiliation) throws Exception {
		if (CollectionUtils.isNotEmpty(creditDetailList)) {
			for (CreditDetailDto creditDetailDto : creditDetailList) {
    	        TCMmCreditDealDetailDTO creditDealDetaildto = new TCMmCreditDealDetailDTO();
				creditDealDetaildto.setTransferId(creditDetailDto.getTransferId());
				creditDealDetaildto.setDealStreamCode(batchId);
				Map<String, Object> searchParamsdeal = new HashMap<String, Object>();
				searchParamsdeal.put("dto", creditDealDetaildto);
				List<TCMmCreditDealDetailDTO>  refList = creditDealDetailDao.searchTCMmCreditDealDetail(searchParamsdeal);
				if (CollectionUtils.isEmpty(refList)) {
					throw new RuntimeException("债权关系表找不到记录，转让编号=" + creditDetailDto.getTransferId() + "，批次号=" + batchId);
				}
				creditDealDetaildto = refList.get(0);
				creditDealDetaildto.setCreditorStatus(creditDetailDto.getDealCreditorStatus()); //交互状态
				creditDealDetaildto.setDeliverDate(creditDetailDto.getDeliverDate());//交割日期
				creditDealDetaildto.setServiceCharge(getVal(creditDetailDto.getServiceCharge()));//服务费	
				creditDealDetaildto.setGuaranteeFee(getVal(creditDetailDto.getGuaranteeFee()));//担保费
    	        creditDealDetaildto.setCautionMoney(getVal(creditDetailDto.getCautionMoney())); //保证金
    	        creditDealDetaildto.setMakeCreditorValue(getVal(creditDetailDto.getMakeCreditorValue())); //转让债权价值
    	        creditDealDetaildto.setCostState(creditDetailDto.getCostState());//结算标识
    	        creditDealDetaildto.setRepaymentAffiliation(creditAffiliation);//月还归属
				Map<String, Object> paramMap = new HashMap<String, Object>();
    	        paramMap.put("dto", creditDealDetaildto);
    	        //更新关系表
    	        creditDealDetailDao.updateDealDetail(paramMap);
			}
		}
	}
	
	/**
	 * 防止null
	 * @param val
	 * @return
	 */
	private BigDecimal getVal(BigDecimal val) {
		if (val == null) {
			return BigDecimal.ZERO;
		}
		return val;
	}
	

	/**
	 * 更新批次表
	 * @param batchId
	 * @throws Exception
	 */
	public void updateBatch(String batchId) throws Exception{
		Map<String, Object> paramMapdealCode = new HashMap<String, Object>();
        // 更新批次表的总费用价值
		paramMapdealCode.put("dealStreamCode", batchId); //交易流水号
		dealDao.updateCooperOrgDerailMakeCostFee(paramMapdealCode);
		
		//查询批次中是否有在途状态的明细
		int  creditCount = dealDao.selectCreditInWayByDealCode(batchId);
		if(creditCount==0){
			// 更新批次表的状态
			TCMmCooperorgDealDTO dto = new TCMmCooperorgDealDTO();
			dto.setDealCode(batchId);
			dto.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_FINISH);// 03 交易完成
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("dto", dto);
			dealDao.updateDealStatus(paramMap); 
		}
	}
	
	/**
	 * 更新批次表
	 * @param batchId
	 * @throws Exception
	 */
	public void updateBatch(List<CreditDetailDto> excelList) throws Exception{
		if (CollectionUtils.isNotEmpty(excelList)) {
			List<String> transferIdList = new ArrayList<String>();
			for (CreditDetailDto detail : excelList) {
				String transferId = detail.getTransferId();
				if (StringUtils.isNotBlank(transferId)) {
					transferIdList.add(transferId);
				}
			}
			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("transferIdList", transferIdList);
			List<String> batchIdList = timeoutDao.queryBatchId(paramMap);
			for (String batchId : batchIdList) {
				updateBatch(batchId);
			}
		}
	}
	
	/**
	 * 获取机构、协议、合约信息
	 * @param dealCode
	 * @return
	 */
	public DealDto getOrgAgreeContract(String dealCode) {
		Map<String, Object> searchParams = new HashMap<String, Object>();
		DealDto dto = new DealDto();
		dto.setDealCode(dealCode);
		searchParams.put("dto", dto);
		QueryReqBean params = new QueryReqBean();
		params.setSearchParams(searchParams);
		PageParameter pageInfo = PageUtil.toPageParameter(new DataMsg());
		params.setPageParameter(pageInfo);
		List<DealDto> dealDtoList = dealDao.getDealListByPaging(params.getSearchParams()); 
		DealDto dealDto = null;
		if(CollectionUtils.isNotEmpty(dealDtoList)){
			dealDto = dealDtoList.get(0);
		} 
		return dealDto;
	}
	

	/**
	 * 查询包信息
	 * @param corpCode
	 * @param corpPackName
	 * @param contractCode
	 * @return
	 */
	public TCMmCreditPackageDTO getPackageInfo(String corpCode, String corpPackName, String contractCode) {
		TCMmCreditPackageDTO creditPackageDTO = creditRightService.getCreditPackageForUnique(corpCode,
												corpPackName, contractCode);
		return creditPackageDTO;
	}
	
	
	/**
	 * 铜板街拆包
	 * @param creditDealList
	 * @param dealCode
	 * @return
	 * @throws Exception
	 */
	public void doSplitPackage(List<CreditDetailDto> creditDealList,String dealCode,String corpCode,
			DealDto dealDto, TCMmCreditPackageDTO creditPackageDTO) throws Exception {
		if (CollectionUtils.isNotEmpty(creditDealList)) {
			CreditDetailDto creditDetailDto = creditDealList.get(0);
			String corpPackName = creditDetailDto.getCooperorgPackageName();
			String currPackName = creditDetailDto.getPackageNum();
			if(CimsConstant.TBJ_COOPERORG_CODE.equals(corpCode) && !currPackName.equals(corpPackName)){
				//铜板街、所属包名与机构理财包名不同，则执行拆包操作
				if (null == creditPackageDTO) {
					//如果包不存在，则创建
					creditPackageDTO = new TCMmCreditPackageDTO();
					creditPackageDTO.setCooperorgCode(dealDto.getCooperorgCode());// 机构编号
					creditPackageDTO.setContractCode(dealDto.getContractCode());// 合约编号
					creditPackageDTO.setCreditPackageName(corpPackName);// 包号
					creditPackageDTO.setBillDate(dealDto.getBillDate());
					creditPackageDTO.setBillDateEnd(dealDto.getBillDateEnd());
					creditPackageDTO.setRepayType(dealDto.getRepayType());
					creditPackageDTO.setIsCorpPack("1");
					creditPackageService.insertTCMmCreditPackage(creditPackageDTO);
				} 
			
				//获取批次号
				StringBuffer dealCodesb = new StringBuffer();
				this.doGetDealCode(dealCodesb);
				String dealCodeNew = dealCodesb.toString();
				// 创建批次流水信息
				dealDto.setDealCode(dealCodeNew);// 交易流水号
				dealDto.setCooperativeAgencyDealStatus(CimsConstant.DEAL_STATUS_WAY);// 在途
				dealDto.setCreditPackageName(corpPackName); // 拆包后的包名
				dealDto.setDealDate(new Date());
				dealDto.setDealCodeOld(dealCode);
				cooperorgDealService.insertTCMmCooperorgDeal(dealDto);
			
				TCMmCreditDealDetailDTO tCMmCreditDealDetailDTO = null;
				CreditDetailDto creditDetailDtoUpdate = null;
				for (CreditDetailDto creditDetail : creditDealList) {
					//更新关系表
					tCMmCreditDealDetailDTO = new TCMmCreditDealDetailDTO();
					tCMmCreditDealDetailDTO.setTransferId(creditDetail.getTransferId());//债权转让编号
					tCMmCreditDealDetailDTO.setDealStreamCodeTbj(dealCodeNew);///铜板街拆包后的流水号
					tCMmCreditDealDetailDTO.setDealStreamCode(dealCode);//我司交易流水号
					tCMmCreditDealDetailService.updateTCMmCreditDealDetailByTransferId(tCMmCreditDealDetailDTO);
					//更新明细表
					creditDetailDtoUpdate = new CreditDetailDto();
					creditDetailDtoUpdate.setTransferId(creditDetail.getTransferId());//债权转让编号
					creditDetailDtoUpdate.setPackageNum(corpPackName);//修改债权包为机构理财包名
					creditDetailDtoUpdate.setCooperorgPackageName(creditDetail.getPackageNum());//机构理财原包名
					tCMmCreditDetailService.updateTCMmCreditDetailByTransferId(creditDetail);
				}
				//更新新批次表状态（总笔数、转让总价值、三费之和、总体状态）
				updateBatch(dealCodeNew);
			}
		}
	}
	
	/**
	 * 铜板街拆包
	 * @param creditDealList
	 * @param dealCode
	 * @return
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void doSplitPackageTimeout(List<CreditDetailDto> creditDealList,String dealCode,String corpCode,
			DealDto dealDto, TCMmCreditPackageDTO creditPackageDTO) throws Exception {
		//拆包
		doSplitPackage(creditDealList, dealCode, corpCode, dealDto, creditPackageDTO);
		//拆包后要重新更新老批次表状态（总笔数、转让总价值、三费之和、总体状态）
		updateBatch(dealCode);
	}

	/**
	 * 债权转让流水号
	 * 
	 * @param quotaCode
	 * @return
	 */
	private JResult doGetDealCode(StringBuffer dealCode) throws Exception {
		JResult result = new JResult();
		dealCode = dealCode.append(iCDeal.createDealCode(CimsConstant.BIZNO_TYPE_CRTO));
		result.setSuccess(true);
		if (StringUtils.isBlank(String.valueOf(dealCode)))
			result.setSuccess(false);
		return result;
	}
	
}
